package com.alogic.reload;

import com.alogic.reload.impl.Default;
import com.anysoft.util.*;
import com.anysoft.util.resource.ResourceFactory;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.InputStream;

/**
 * Reload工厂类
 * @since 1.6.13.5 [20200605 duanyy] <br>
 */
public class ReloadFactory extends Factory<Reloader>{
    /**
     * a logger of log4j
     */
    protected static final Logger LOG = LoggerFactory.getLogger(ReloadFactory.class);

    /**
     * 缺省配置文件地址
     */
    protected static final String DEFAULT = "java:///com/alogic/reload/reload.default.xml#" + Reloader.class.getName();

    /**
     * 唯一实例
     */
    protected static Reloader INSTANCE = null;

    /**
     * 获取缺省的实现类名
     * @return 实现类名
     */
    protected String getDefaultClass(){
        return Default.class.getName();
    }

    /**
     * 获取系统唯一实例
     * @return 系统唯一实例
     */
    public static Reloader getReloader(){
        if (INSTANCE == null){
            synchronized (Reloader.class){
                if (INSTANCE == null){
                    Settings p = Settings.get();
                    String master = PropertiesConstants.getString(p, "reload.master", DEFAULT);
                    String secondary = PropertiesConstants.getString(p, "reload.secondary", DEFAULT);
                    ReloadFactory f = new ReloadFactory();
                    INSTANCE = f.loadFrom(master,secondary);
                }
            }
        }
        return INSTANCE;
    }

    public Reloader loadFrom(Element root, String moduleAttr, Properties p) {
        Reloader loader = null;
        try {
            Factory<Reloader> f = new Factory<Reloader>();
            loader = f.newInstance(root, p, moduleAttr, getDefaultClass());
        }catch (Exception ex){
            LOG.error(String.format("Can not create loader with %s", XmlTools.node2String(root)));
        }
        return loader;
    }

    /**
     * 从xml配置节点上装入Loader
     *
     * @param root xml配置节点
     * @param p 环境变量集
     * @return Loader实例
     */
    public Reloader loadFrom(Element root, Properties p){
        return loadFrom(root,"module",p);
    }

    /**
     * 从xml文档的根节点装入loader
     * @param doc xml文档
     * @param p 环境变量集
     * @return Loader实例
     */
    public Reloader loadFrom(Document doc, Properties p){
        return loadFrom(doc.getDocumentElement(),p);
    }

    /**
     * 从配置文件的路径中装入
     * @param master 主路径
     * @param secondary 备用路径
     * @return Loader实例
     */
    public Reloader loadFrom(String master, String secondary){
        Reloader reloader = null;
        ResourceFactory rf = Settings.getResourceFactory();
        InputStream in = null;
        try {
            in = rf.load(master, secondary, null);
            Document doc = XmlTools.loadFromInputStream(in);
            reloader = loadFrom(doc,Settings.get());
        } catch (Exception ex) {
            LOG.error("Error occurs when load xml file,source=" + master);
            LOG.error(ExceptionUtils.getStackTrace(ex));
        } finally {
            IOTools.closeStream(in);
        }
        return reloader;
    }
}
